/**
 * Validation utility functions tests
 */

import '@testing-library/jest-dom';

// Validation utils
export const validateEmail = (email: string): boolean => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
};

export const validatePassword = (password: string): {
  isValid: boolean;
  errors: string[];
} => {
  const errors: string[] = [];

  if (password.length < 8) {
    errors.push('密码长度至少8位');
  }
  if (!/[A-Z]/.test(password)) {
    errors.push('密码必须包含大写字母');
  }
  if (!/[a-z]/.test(password)) {
    errors.push('密码必须包含小写字母');
  }
  if (!/\d/.test(password)) {
    errors.push('密码必须包含数字');
  }
  if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
    errors.push('密码必须包含特殊字符');
  }

  return {
    isValid: errors.length === 0,
    errors
  };
};

export const validateRequired = (value: any, fieldName: string): string | null => {
  if (value === null || value === undefined || value === '') {
    return `${fieldName}是必填项`;
  }
  return null;
};

export const validateLength = (
  value: string,
  minLength: number,
  maxLength: number,
  fieldName: string
): string | null => {
  if (value.length < minLength) {
    return `${fieldName}长度不能少于${minLength}个字符`;
  }
  if (value.length > maxLength) {
    return `${fieldName}长度不能超过${maxLength}个字符`;
  }
  return null;
};

export const validateNumeric = (value: string, fieldName: string): string | null => {
  if (!/^\d+$/.test(value)) {
    return `${fieldName}必须是数字`;
  }
  return null;
};

export const validatePhone = (phone: string): string | null => {
  const phoneRegex = /^1[3-9]\d{9}$/;
  if (!phoneRegex.test(phone)) {
    return '手机号码格式不正确';
  }
  return null;
};

describe('Validation Utils', () => {
  describe('validateEmail', () => {
    test('returns true for valid email', () => {
      expect(validateEmail('test@example.com')).toBe(true);
      expect(validateEmail('user.name@domain.co.uk')).toBe(true);
    });

    test('returns false for invalid email', () => {
      expect(validateEmail('invalid-email')).toBe(false);
      expect(validateEmail('test@')).toBe(false);
      expect(validateEmail('@example.com')).toBe(false);
      expect(validateEmail('')).toBe(false);
    });
  });

  describe('validatePassword', () => {
    test('validates strong password correctly', () => {
      const result = validatePassword('StrongPass123!');
      expect(result.isValid).toBe(true);
      expect(result.errors).toHaveLength(0);
    });

    test('detects weak password - too short', () => {
      const result = validatePassword('weak');
      expect(result.isValid).toBe(false);
      expect(result.errors).toContain('密码长度至少8位');
    });

    test('detects weak password - no uppercase', () => {
      const result = validatePassword('weakpass123!');
      expect(result.isValid).toBe(false);
      expect(result.errors).toContain('密码必须包含大写字母');
    });

    test('detects weak password - no lowercase', () => {
      const result = validatePassword('WEAKPASS123!');
      expect(result.isValid).toBe(false);
      expect(result.errors).toContain('密码必须包含小写字母');
    });

    test('detects weak password - no numbers', () => {
      const result = validatePassword('WeakPassword!');
      expect(result.isValid).toBe(false);
      expect(result.errors).toContain('密码必须包含数字');
    });

    test('detects weak password - no special characters', () => {
      const result = validatePassword('WeakPassword123');
      expect(result.isValid).toBe(false);
      expect(result.errors).toContain('密码必须包含特殊字符');
    });

    test('returns multiple errors for very weak password', () => {
      const result = validatePassword('weak');
      expect(result.isValid).toBe(false);
      expect(result.errors.length).toBeGreaterThan(1);
    });
  });

  describe('validateRequired', () => {
    test('returns null for non-empty value', () => {
      expect(validateRequired('test', '字段名')).toBeNull();
      expect(validateRequired(123, '字段名')).toBeNull();
      expect(validateRequired(false, '字段名')).toBeNull();
    });

    test('returns error message for empty value', () => {
      expect(validateRequired('', '字段名')).toBe('字段名是必填项');
      expect(validateRequired(null, '字段名')).toBe('字段名是必填项');
      expect(validateRequired(undefined, '字段名')).toBe('字段名是必填项');
    });
  });

  describe('validateLength', () => {
    test('returns null for valid length', () => {
      expect(validateLength('test', 3, 10, '字段名')).toBeNull();
      expect(validateLength('1234567890', 5, 15, '字段名')).toBeNull();
    });

    test('returns error for too short', () => {
      expect(validateLength('ab', 3, 10, '字段名')).toBe('字段名长度不能少于3个字符');
    });

    test('returns error for too long', () => {
      expect(validateLength('12345678901', 5, 10, '字段名')).toBe('字段名长度不能超过10个字符');
    });
  });

  describe('validateNumeric', () => {
    test('returns null for numeric string', () => {
      expect(validateNumeric('123', '字段名')).toBeNull();
      expect(validateNumeric('0', '字段名')).toBeNull();
    });

    test('returns error for non-numeric string', () => {
      expect(validateNumeric('abc', '字段名')).toBe('字段名必须是数字');
      expect(validateNumeric('12a34', '字段名')).toBe('字段名必须是数字');
      expect(validateNumeric('12.34', '字段名')).toBe('字段名必须是数字');
    });
  });

  describe('validatePhone', () => {
    test('returns null for valid phone number', () => {
      expect(validatePhone('13812345678')).toBeNull();
      expect(validatePhone('15912345678')).toBeNull();
      expect(validatePhone('18812345678')).toBeNull();
    });

    test('returns error for invalid phone number', () => {
      expect(validatePhone('12345678')).toBe('手机号码格式不正确');
      expect(validatePhone('02812345678')).toBe('手机号码格式不正确');
      expect(validatePhone('1381234567')).toBe('手机号码格式不正确');
      expect(validatePhone('138123456789')).toBe('手机号码格式不正确');
    });
  });
});